package com.pearl.jacksoncore.demo.feature;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.json.JsonReadFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;

import java.math.BigDecimal;
import java.util.Date;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;

/**
 * @author TD
 * @version 1.0
 * @date 2024/4/2
 */
public class SerializationFeatureTest {

    public static void main(String[] args) throws JsonProcessingException {
        User user = new User();
        user.setId(1767798780627279333L);
        user.setName("https://www.baidu.com/");
        user.setaDouble(Double.NaN);
        JsonFactory jsonFactory = JsonFactory.builder()
                .configure(JsonReadFeature.ALLOW_MISSING_VALUES, true)// 配置特性
                .build();
        JsonMapper jsonMapper = new JsonMapper(jsonFactory);
        jsonMapper.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
        jsonMapper.configure(SerializationFeature.INDENT_OUTPUT, false);
        jsonMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        jsonMapper.configure(SerializationFeature.FAIL_ON_SELF_REFERENCES, true);
        jsonMapper.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS, true);
        jsonMapper.configure(SerializationFeature.WRITE_DATES_WITH_ZONE_ID, false);

        user.setBirthday(new Date());
        String jsonStrAA = jsonMapper.writeValueAsString(user);
        System.out.println(jsonStrAA);

        // WRITE_DATE_KEYS_AS_TIMESTAMPS
        Map<Date, Object> map = new HashMap<>();
        map.put(new Date(), "test");
        String jsonStrMap = jsonMapper.writeValueAsString(map);
        System.out.println(jsonStrMap);

        //
        // 创建一个包含时区信息的ZonedDateTime对象
/*        ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
        String disabledZoneIdOutput = jsonMapper.writeValueAsString(zonedDateTime);
        System.out.println(disabledZoneIdOutput);*/


/*        ObjectMapper objectMapper = new ObjectMapper();
        // 创建一个 Duration 对象
        Duration duration = Duration.ofSeconds(123);
        // 启用 WRITE_DURATIONS_AS_TIMESTAMPS 特性
        objectMapper.enable(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS);
        // 序列化 Duration 对象
        String serializedWithTimestamps = objectMapper.writeValueAsString(duration);
        System.out.println("Serialized with timestamps: " + serializedWithTimestamps);
        // 禁用 WRITE_DURATIONS_AS_TIMESTAMPS 特性
        objectMapper.disable(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS);
        // 序列化 Duration 对象为文本形式
        String serializedAsText = objectMapper.writeValueAsString(duration);
        System.out.println("Serialized as text: " + serializedAsText);*/


        // WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS
        char[] charArray = {'H', 'e', 'l', 'l', 'o'};        // 创建一个字符数组
        String serializedAsJsonArray = jsonMapper.writeValueAsString(charArray);  // 序列化字符数组为 JSON 数组
        System.out.println("Serialized as JSON array: " + serializedAsJsonArray);
        jsonMapper.configure(SerializationFeature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS, true); // 开启 WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS 特性
        String serializedAsString = jsonMapper.writeValueAsString(charArray);// 序列化字符数组为 JSON 字符串（默认行为）
        System.out.println("Serialized as JSON string: " + serializedAsString);

        // WRITE_ENUMS_USING_TO_STRING
        Color color = Color.RED;
        String serializedWithToString = jsonMapper.writeValueAsString(color); // 序列化枚举实例为 JSON 字符串（使用 toString() 的结果 这是默认行为）
        System.out.println("Serialized with toString(): " + serializedWithToString);

        jsonMapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING,false); // 启用 WRITE_ENUMS_USING_TO_STRING 特性
        String serializedWithDefault = jsonMapper.writeValueAsString(color);// 序列化枚举实例为 JSON 字符串（使用枚举常量的名称）
        System.out.println("Serialized with default: " + serializedWithDefault);


        // WRITE_ENUMS_USING_INDEX
        String serializedWithNo = jsonMapper.writeValueAsString(color); // 序列化枚举实例为 JSON 字符串（使用枚举常量的名称，这是默认行为）
        System.out.println("Serialized with default: " + serializedWithNo);

        jsonMapper.configure(SerializationFeature.WRITE_ENUMS_USING_INDEX,true);       // 启用 WRITE_ENUMS_USING_INDEX 特性
        String serializedWithIndex = jsonMapper.writeValueAsString(color);// 序列化枚举实例为 JSON 字符串（使用枚举常量的索引）
        System.out.println("Serialized with index: " + serializedWithIndex);

        // WRITE_ENUM_KEYS_USING_INDEX
        Map<Color, String> colorMap = new EnumMap<>(Color.class);
        colorMap.put(Color.RED, "Red color");
        colorMap.put(Color.GREEN, "Green color");
        colorMap.put(Color.BLUE, "Blue color");
        String serializedWithColorMap = jsonMapper.writeValueAsString(colorMap);  // 序列化包含枚举键的 Map 为 JSON 字符串（使用枚举常量的名称）
        System.out.println("Serialized with default: " + serializedWithColorMap);

        jsonMapper.configure(SerializationFeature.WRITE_ENUM_KEYS_USING_INDEX ,true);       // 启用 WRITE_ENUM_KEYS_USING_INDEX  特性
        String serializedWithEnumIndex = jsonMapper.writeValueAsString(colorMap);  // 序列化包含枚举键的 Map 为 JSON 字符串
        System.out.println("Serialized with index: " + serializedWithEnumIndex);

        // WRITE_NULL_MAP_VALUES
        // 创建一个包含 null 值的 Map
        Map<String, String> mapWithNullValue = new HashMap<>();
        mapWithNullValue.put("key1", "value1");
        mapWithNullValue.put("key2", null); // 这个值为 null
        mapWithNullValue.put("key3", "value3");
        // 序列化 Map 为 JSON 字符串（包含 null 值，默认行为）
        String serializedWithoutNullValues = jsonMapper.writeValueAsString(mapWithNullValue);
        System.out.println("Serialized without null values: " + serializedWithoutNullValues);

        // 序列化 Map 为 JSON 字符串（不包含 null 值）
        jsonMapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES ,false);               // 关闭 WRITE_NULL_MAP_VALUES 特性
        String serializedWithNullValues = jsonMapper.writeValueAsString(mapWithNullValue);
        System.out.println("Serialized with null values: " + serializedWithNullValues);

        // WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED
        int[] singleElementArray = {1};
        String serializedWithList = jsonMapper.writeValueAsString(singleElementArray);
        System.out.println(serializedWithList);

        jsonMapper.configure(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED ,true);
        String serializedWithElementArray = jsonMapper.writeValueAsString(singleElementArray);
        System.out.println(serializedWithElementArray);

        // WRITE_BIGDECIMAL_AS_PLAIN
        user.setNum(new BigDecimal(123456789.987654321));
        String serializedWithBigDecimal = jsonMapper.writeValueAsString(user);
        System.out.println(serializedWithBigDecimal);

        jsonMapper.configure(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN ,false);
        String serializedWithWRITE_BIGDECIMAL_AS_PLAIN = jsonMapper.writeValueAsString(user);
        System.out.println(serializedWithWRITE_BIGDECIMAL_AS_PLAIN);

        // WRITE_BIGDECIMAL_AS_PLAIN
        // 创建一个 Instant 实例（代表一个时间点）
/*        Instant instant = Instant.now();
        // 序列化 Instant 到 JSON
        String jsonWithNanoseconds = jsonMapper.writeValueAsString(instant);
        // 输出结果（将以纳秒为单位的时间戳形式呈现）
        System.out.println(jsonWithNanoseconds);

        // 禁用 WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS 特性
        jsonMapper.disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);
        String jsonWithoutNanoseconds = jsonMapper.writeValueAsString(instant);
        // 输出结果（将以默认的时间戳形式呈现，通常不包含纳秒部分）
        System.out.println(jsonWithoutNanoseconds);*/

        //
        Map<String, String> unorderedMap = new HashMap<>();    // 创建一个未排序的 HashMap
        unorderedMap.put("c", "value3");
        unorderedMap.put("a", "value1");
        unorderedMap.put("b", "value2");
        jsonMapper.enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS); // 开启
        String jsonUnordered = jsonMapper.writeValueAsString(unorderedMap);    // 序列化 HashMap 到 JSON
        System.out.println(jsonUnordered);       // 输出结果（将按照键的字典顺序排序）

        // 创建两个相互引用的Person对象
/*        Person person1 = new Person("Alice", null);
        Person person2 = new Person("Bob", person1);
        person1.setSpouse(person2); // 现在person1和person2相互引用
        jsonMapper.configure(SerializationFeature.WRITE_SELF_REFERENCES_AS_NULL,true); // 开启
        String json = jsonMapper.writeValueAsString(person1);
        System.out.println(json);*/

// 创建两个相互引用的Person对象
        Person person1 = new Person("Alice", null);
        Person person2 = new Person("Bob", person1);
        person1.setSpouse(person2); // 现在person1和person2相互引用

        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.WRITE_SELF_REFERENCES_AS_NULL); // 启用特性

        // 序列化Person对象
        String json = mapper.writeValueAsString(person1);

        // 输出JSON字符串
        System.out.println(json);
// 创建一个包含自我引用的 Node 对象
/*        Node nodeA = new Node("A");
        Node nodeB = new Node("B");
        nodeA.setNext(nodeB);
        nodeB.setNext(nodeA); // 这里创建了自我引用
        jsonMapper.enable(SerializationFeature.WRITE_SELF_REFERENCES_AS_NULL); // 开启
        String json = jsonMapper.writeValueAsString(nodeA);
        System.out.println(json);*/
    }
}
